跳到主要内容

Java Netty 提供的几种传输包

Netty 提供的传输包​

Netty 内置了一些可开箱即用的传输包。因为并不是它们所有的传输都支持每一种协议,所以你必须选择一个和你的应用程序所使用的协议相容的传输工具。

其中 OIO 已经不再支持了,就不介绍了

接下来就讨论这些传输包

NIO 非阻塞 IO​

NIO 提供了一个所有 I/O 操作的全异步的实现。它主要使用自 NIO 子系统被引入 JDK 1. 4 时便可用的基于选择器的API。

选择器背后的基本概念是充当一个注册表,在那里你将可以请求在 Channel 的状态发生变化时得到通知。可能的状态变化有:

  • 新的 Channel 已被接受并且就绪;
  • Channel 连接已经完成;
  • Channel 有已经就绪的可供读取的数据;
  • Channel 可用于写数据。

选择器运行在一个检查状态变化并对其做出相应响应的线程上,在应用程序对状态的改变做出响应之后,选择器将会被重置,并将重复这个过程。

但是 Netty 这个框架内部屏蔽了这些细节,如下图所示:

Epoll 用于 Linux 的本地非阻塞传输​

Netty 的 NIO 传输基于 Java 提供的异步/非阻塞网络编程的通用抽象。虽然这保证了 Netty 的非阻塞 API 可以在任何平台上使用,但它也包含了相应的限制,因为 JDK 为了在所有系统上提供相同的功能,必须做出妥协。

Linux 作为高性能网络编程的平台,其重要性与日俱增,这催生了大量先进特性的开发,其中包括 epoll (IO 多路复用)一个高度可扩展的 I/O 事件通知特性。

这个 API 自 Linux 内核版本 2.5.44 (2002) 被引入,提供了比旧的 POSIX select 和 poll 系统调用有更好的性能,同时现在也是 Linux 上非阻塞网络编程的事实标准。

实际上 Linux JDK NIO API 使用了这些 epoll 调用。

Netty 为 Linux 提供了一组 NIO API, 其以一种和它本身的设计更加一致的方式使用 epoll,并且以一种更加轻量的方式使用中断。高负载下它的性能要优于 JDK 的 NIO 实现。

这个传输的语义与上图所示的完全相同,而且它的用法也是简单直接的。如果要在那个代码清单中使用 epoll 替代 NIO,只需要将 NioEventLoopGroup 替换为 EpollEventLoopGroup,并且将 NioServerSocketChannel.class 替换为 EpollServerSocketChannel.class 即可。

用于 JVM 内部通信的 Local 传输​

Netty 提供了一个 Local 传输,用于在同一个 JVM 中运行的客户端和服务器程序之间的异步通信。同样,这个传输也支持对于所有 Netty 传输实现都共同的 API。

在这个传输中,和服务器 Channel 相关联的 SocketAddress 并没有绑定物理网络地址;相反,只要服务器还在运行,它就会被存储在注册表里,并在 Channel 关闭时注销。因为这个传输并不接受真正的网络流量,所以它并不能够和其他传输实现进行互操作。

因此,客户端希望连接到(在同一个 JVM 中)使用了这个传输的服务器端时也必须使用它。除了这个限制,它的使用方式和其他的传输一模一样。

Embedded 传输​

Netty 提供了一种额外的传输,使得你可以将一组 ChannelHandler 作为帮助器类嵌入到其他的 ChannelHandler 内部。通过这种方式,你将可以扩展一个 ChannelHandler 的功能,而又不需要修改其内部代码。

各种传输的应用场景​